import numpy
import math

def create_dataset(dataset, scale):
    '''
    创建数据集pi
    :param dataset: array/ndarray
    :param scale:  number
    :return:  array/ndarray  divided train and test dataset
    '''
    # 训练数据集为原始数据集的0.90
    train_size = int(len(dataset) * scale)
    # 将数据集分为两部分
    train, test = dataset[0:train_size], dataset[train_size:]
    # train, test = dataset.iloc[0:train_size], dataset.iloc[train_size:]
    return train, test


def set_label_dataset(dataset, scale):
    '''
    获取标签数据，即，根据预测的范围通过平移scale来对应预测的对象，根据x_dataset 预测y_dataset
    :param dataset: array/ndarray
    :param scale:  number
    :return: divided dataset map from x_dataset to y_dataset
    '''
    dataset_cut = int(scale)
    x_dataset, y_dataset = dataset[:-dataset_cut], dataset[dataset_cut:]
    # x_dataset, y_dataset = dataset.iloc[:-dataset_cut], dataset.iloc[dataset_cut:]
    return x_dataset, y_dataset


def mean_absolute_percentage_error(y_true, y_pred):
    '''
    平均绝对百分比误差（MAPE）的计算
    :param y_true:
    :param y_pred:
    :return:
    '''
    y_true, y_pred = numpy.array(y_true), numpy.array(y_pred)
    return numpy.mean(numpy.abs((y_true - y_pred) / y_true)) * 100


def get_r2_numpy(x, y):
    result = numpy.polyfit(x, y, 1)  #polyfit为最小二乘多项式拟合，返回多项式的系数矩阵
    slope, intercept = result[0],result[1] # get ax + b   ，a = slop ,b = intercept
    r_squared = 1 - (sum((y - (slope * x + intercept)) ** 2) / ((len(y) - 1) * numpy.var(y, ddof=1)))
    return r_squared


def score_R2(ans, y_test):
    pmean = numpy.mean(y_test)
    omean = numpy.mean(ans)
    SSR = 0.0
    varp = 0.0
    varo = 0.0
    for i in range(0, len(y_test)):
        diffXXbar = y_test[i] - pmean
        difYYbar = ans[i] - omean
        SSR += (diffXXbar * difYYbar)
        varo += diffXXbar ** 2
        varp += difYYbar ** 2
    SST = math.sqrt(varo * varp)
    return (SSR / SST) ** 2

